function ArticleAssistant(articles, id) {
    this.articles = articles;
    this.id = id;
}

ArticleAssistant.prototype = {
    setup: function() {
        this.articleLoaded = this.articleLoaded.bind(this);
        this.articleLoadFailure = this.articleLoadFailure.bind(this);
        this.commentsLoaded = this.commentsLoaded.bind(this);
        this.commentsLoadFailure = this.commentsLoadFailure.bind(this);
        this.adLoaded = this.adLoaded.bind(this);
        
        this.fetchAd();
        this.fetchComments();
        
        if(this.articles[this.id].content === undefined) {
            this.controller.setupWidget("articleSpin",
                { spinnerSize: "small"},
                { spinning: true}
            );
            $("articleText").innerHTML = this.articles[this.id].excerpt + '<br><br>Loading rest of article...';
            this.fetchArticle();
        }
        else {
            $("articleText").innerHTML = this.articles[this.id].content;
        }
        $("articleTitle").innerHTML = this.articles[this.id].title;
        this.onHeaderTap();
        
        this.controller.setupWidget("articleScroller", {}, {
                mode: 'vertical'
            }
        );
        
        this.onResize = this.onResize.bindAsEventListener(this);
        this.controller.listen(this.controller.window, 'resize', this.onResize, false);
        this.onResize();

        this.onHeaderTap = this.onHeaderTap.bind(this);
        this.controller.listen("articleTitle", Mojo.Event.tap, this.onHeaderTap);

        this.onBrowserTap = this.onBrowserTap.bind(this);
        this.controller.listen("browserIcon", Mojo.Event.tap, this.onBrowserTap);

        this.onShareTap = this.onShareTap.bind(this);
        this.controller.listen("shareIcon", Mojo.Event.tap, this.onShareTap);
        
        this.onFlick = this.onFlick.bind(this);
        this.controller.listen(this.controller.window, Mojo.Event.flick, this.onFlick);
        
        this.handlePop = this.handlePop.bind(this);
        this.facebookFailure1 = this.facebookFailure1.bind(this);
        this.facebookFailure2 = this.facebookFailure2.bind(this);
    },
    fetchArticle: function() {
        this.articleRequest = new Ajax.Request("http://www.webosroundup.com/ajax.php", {
            method: 'get',
            parameters: {post_id: this.articles[this.id].id},
            evalJSON: 'force',
            onSuccess: this.articleLoaded,
            onFailure: this.articleLoadFailure
            // TODO: write handlers
        });
    },
    fetchComments: function() {
        $("comments").hide();
        this.commentRequest = new Ajax.Request("http://www.webosroundup.com/ajax.php", {
            method: 'get',
            parameters: {post_id: this.articles[this.id].id, comments: 1},
            evalJSON: 'force',
            onSuccess: this.commentsLoaded,
            onFailure: this.commentsLoadFailure
            // TODO: write handlers
        });
    },
    fetchAd: function() {
        this.AdRequest = new Ajax.Request("http://sponsors.webosroundup.com/home/app", {
            method: 'get',
            parameters: {},
            evalJSON: 'force',
            onSuccess: this.adLoaded
            // ignoring ad load failure
        });
    },
    articleLoaded: function(response) {
        var posted;
        
        if(!this.goingAway && (response.status >= 200) && (response.status <= 204)) {
            if(this.articles[this.id].posted != this.articles[this.id].modified) {
                posted = this.articles[this.id].posted + '<br>Last updated: ' + this.articles[this.id].modified;
            }
            else {
                posted = this.articles[this.id].posted;
            }
            $("articleText").innerHTML = response.responseJSON.content + '<br><div class="postInfo">' +
                $L('Posted by') + ': ' + this.articles[this.id].author + ' ' + $L("on") + ' ' + posted + '</div>';
            $("articleText").select("img").each(function(el) {
                if((el.parentNode.tagName == "A") && (el.src == el.parentNode.href)) {
                    el.parentNode.replace(el);    // In theory, replace anchor tag with element
                }
            });
            this.articles[this.id].content = $("articleText").innerHTML;    // TODO: Is this a good idea?
            $("articleSpin").mojo.stop();
            $("articleSpin").hide();
        }
        else {
            this.articleLoadFailure(response);
        }
    },
    articleLoadFailure: function(response) {
        // TODO: Pop up failure icon with retry button
    },
    commentsLoaded: function(response) {
        var i, output = '<div class="commentWrapper"><div class="commentHeader">' + $L("Comments") + ':</div>';
        
        if(!this.goingAway && (response.status >= 200) && (response.status <= 204)) {
            for(i = 0; i < response.responseJSON.length; i++) {
                output += '<div class="comment"><hr />' +
                    response.responseJSON[i].comment_content +
                    '</div><div class="commentAuthor">' + $L("by") + ': ' +
                    response.responseJSON[i].comment_author +
                    '</div><div class="commentDate">' + $L("on") + ': ' +
                    response.responseJSON[i].comment_date +
                    '</div>';
            }
            output += "</div>";
            $("comments").show();
            $("comments").innerHTML = output;
//            $("articleSpin").mojo.stop();
//            $("articleSpin").hide();
        }
        else {
            this.commentsFailure(response);
        }
    },
    commentsLoadFailure: function(response) {
        $("comments").innerHTML = '<div class="commentFailure">Comments failed to load!</div>';
    },
    adLoaded: function(response) {
        if(!this.goingAway && (response.status >= 200) && (response.status <= 204)) {
            $("adSpot").innerHTML = '<a href="' + response.responseJSON.TargetURL + '"><img src="' +
                response.responseJSON.ImagePath + '"></a>';
        }
    },
    onResize: function(event) {
        $("articleScroller").style.height = (this.controller.window.innerHeight -
            ($("articleHeaderWrap").getHeight() + 41)) + "px";
        //$("articleWrap").style.height = this.controller.window.innerHeight + "px";
    },
    onHeaderTap: function(event) {
        $("articleTitle").toggleClassName("clipped");
    },
    onBrowserTap: function(event) {
        // Should just make the icon a link!

        this.controller.serviceRequest("palm://com.palm.applicationManager", {
            method: "open",
            parameters:  {
                id: 'com.palm.app.browser',
                params: {
                    target: this.articles[this.id].permalink
                }
            }
        });
    },
    onShareTap: function(event) {
        this.controller.popupSubmenu({
            onChoose: this.handlePop,
            placeNear: $("shareIcon"),
            items: [
                { label: $L("Email"), command: "email" },
                { label: $L("SMS"), command: "sms" },
                { label: $L("Facebook"), command: "facebook" },
                { label: $L("Clipboard"), command: "clip" }
            ]
        });
    },
    handlePop: function(value) {
        var summary = this.articles[this.id].excerpt;
        
        if(summary == '') {
            if(this.articles[this.id].content.length > 500) {
                summary = this.articles[this.id].content.substr(0,500) + '...';
            }
            else {
                summary = this.articles[this.id].content;
            }
        }
        if(value === "email") {
            this.controller.serviceRequest("palm://com.palm.applicationManager", {
                method: "open",
                parameters:  {
                    id: 'com.palm.app.email',
                    params: {
                        summary: "webOSroundup: " + this.articles[this.id].title,
                        text: summary + '<br><br><a href="' +
                            this.articles[this.id].permalink + '">Full Article at webOSroundup</a><br><br>'
                    }
                }
            });
        }
        else if(value === "sms") {
            this.controller.serviceRequest("palm://com.palm.applicationManager", {
                method: "launch",
                parameters:  {
                    id: 'com.palm.app.messaging',
                    params: {
                        messageText: this.articles[this.id].title + ' @ ' + this.articles[this.id].permalink
                    }
                }
            });
        }
        else if(value === "facebook") {
            this.controller.serviceRequest("palm://com.palm.applicationManager", {
                method: "launch",
                parameters:  {
                    id: 'com.palm.app.facebook',
                    params: {
                        status: 'Check out this webOSroundup article: ' +  this.articles[this.id].title +
                        ' -- ' + this.articles[this.id].permalink
                    }
                },
                onFailure: this.facebookFailure1
            });
        }
        else if(value === "clip") {
            this.controller.stageController.setClipboard(this.articles[this.id].title + ' @ ' + this.articles[this.id].permalink, true);
            Mojo.Controller.getAppController().showBanner("Saved to clipboard...",
                {source: 'notification'});
        }
    },
    facebookFailure1: function(event) {
        this.controller.serviceRequest("palm://com.palm.applicationManager", {
            method: "launch",
            parameters:  {
                id: 'com.palm.app.facebook.beta',
                params: {
                    status: 'Check out this webOSroundup article: ' +  this.articles[this.id].title +
                    ' -- ' + this.articles[this.id].permalink
                }
            },
            onFailure: this.facebookFailure2
        });
    },
    facebookFailure2: function(event) {
        Mojo.Controller.getAppController().showBanner("Facebook app not installed!",
            {source: 'notification'});
    },
    onFlick: function(event) {
        var x, y;
        
        x = event.velocity.x;
        y = event.velocity.y;
        
        if(Math.abs(x) > Math.abs(y)) {
            if((x < 0) && (this.id < (this.articles.length-1))) {
                Mojo.Controller.stageController.swapScene(
                    {
                        name: "article",
                        disableSceneScroller: true
                    },
                    this.articles,
                    this.id + 1
                );
            }
            else if((x > 0) && (this.id > 0)) {
                Mojo.Controller.stageController.swapScene(
                    {
                        name: "article",
                        disableSceneScroller: true
                    },
                    this.articles,
                    this.id - 1
                );
            }
        }
    },
    activate: function(event) {
    },
    deactivate: function(event) {
        this.goingAway = true;
    },
    cleanup: function() {
        this.controller.stopListening(this.controller.window, 'resize', this.onResize, false);
        this.controller.stopListening("browserIcon", Mojo.Event.tap, this.onBrowserTap);
        this.controller.stopListening("shareIcon", Mojo.Event.tap, this.onShareTap);
        this.controller.stopListening("articleTitle", Mojo.Event.tap, this.onHeaderTap);
        this.controller.stopListening(this.controller.window, Mojo.Event.flick, this.onFlick);
    }
};